package com.pxst.et.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pxst.et.entity.NonMerchantStatementExcelModel;
import com.pxst.et.mapper.NonMerchantStatementMapper;
import com.pxst.et.req.NonMerchantStatementReq;
import com.pxst.et.resp.NonMerchantStatementResp;
import com.pxst.et.service.NonMerchantStatementService;
import com.pxst.internalReports.entity.SysBankBillRemarkEntity;
import com.pxst.internalReports.entity.SysXyExceptionRecordEntity;
import com.pxst.internalReports.mapper.SysBankBillRemarkEntityMapper;
import com.pxst.internalReports.mapper.SysXyExceptionRecordEntityMapper;
import com.pxst.resp.ApiResp;
import com.pxst.utils.AltIdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.pxst.et.constants.EtConstant.*;

/**
 * @author rj
 * @create 2023-11-03-10:54
 */
@Service
public class NonMerchantStatementServiceImpl implements NonMerchantStatementService {

    @Autowired
    private NonMerchantStatementMapper nonMerchantStatementMapper;

    @Autowired
    private SysXyExceptionRecordEntityMapper xyExceptionRecordEntityMapper;

    @Autowired
    private SysBankBillRemarkEntityMapper bankBillRemarkEntityMapper;

    @Override
    public ApiResp<Page<NonMerchantStatementResp>> getPage(NonMerchantStatementReq req) {
        // 查询前处理
        String commandId = req.getCommandId();
        if (!StringUtils.isEmpty(commandId)){
            req = preQueryProcessing(req);
        }
        // 分页查询
        PageHelper.startPage(req.getPage(), req.getRp());
        Page<NonMerchantStatementResp> respPage = (Page<NonMerchantStatementResp>)nonMerchantStatementMapper.selectNoMerchantStatementList(req);
        // 查询后处理
        List<NonMerchantStatementResp> nonMerchantStatementResps = afterQueryProcessing(respPage.getResult());
        return ApiResp.page(req.getPage(), req.getRp(), (int) respPage.getTotal(), nonMerchantStatementResps);
    }

    @Override
    public List<NonMerchantStatementExcelModel> download(NonMerchantStatementReq req) {
        // 查询前处理
        String commandId = req.getCommandId();
        if (!StringUtils.isEmpty(commandId)){
            req = preQueryProcessing(req);
        }
        List<NonMerchantStatementResp> list = nonMerchantStatementMapper.selectNoMerchantStatementList(req);
        // 查询后处理
        List<NonMerchantStatementResp> nonMerchantStatementResps = afterQueryProcessing(list);
        // 封装汇出报表数据
        return addDataForExcel(nonMerchantStatementResps);
    }

    /**
     * 封装需要汇出报表的数据
     *
     * @param nonMerchantStatementResps
     */
    private List<NonMerchantStatementExcelModel> addDataForExcel(List<NonMerchantStatementResp> nonMerchantStatementResps) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return nonMerchantStatementResps.stream().map(resp -> {
            NonMerchantStatementExcelModel model = new NonMerchantStatementExcelModel();
            model.setVbsId(resp.getVbId());
            model.setBank(resp.getBankName());
            model.setAccountCode(resp.getBankCardAccCode());
            model.setTransactionTime(format.format(resp.getTransactionDate()));
            model.setDescription(resp.getDescription());
            model.setNote(resp.getNote());
            model.setDebit(resp.getDebit());
            model.setCredit(resp.getCredit());
            model.setCreated(format.format(resp.getCreatedAt()));
            model.setCreatedBy(resp.getCreator());
            model.setUpdated(format.format(resp.getUpdatedAt()));
            model.setUpdatedBy(resp.getUpdater());
            model.setTxnId(StringUtils.isEmpty(resp.getRefVbsId()) ? resp.getCommandId() : "VBS\n#" + resp.getRefVbsId());
            model.setBankFee(resp.getBankFee());
            model.setType(processType(resp.getType()));
            return model;
        }).collect(Collectors.toList());
    }

    private String processType(Integer type) {
        Map<Integer, String> typeMap = new HashMap();
        typeMap.put(TYPE_FI, "Deposit/充值");
        typeMap.put(TYPE_FO, "Deposit/充值");
        typeMap.put(TYPE_FX, "Settlement/下发");
        typeMap.put(TYPE_TR, "Internal transfer/内转");
        typeMap.put(TYPE_BANK_CHARGE, "Bank Charges/银行手续费");
        typeMap.put(TYPE_BANK_INTEREST, "Bank interest/银行利息");
        typeMap.put(TYPE_UNCLAIMED_FUND, "Unclaimed fund/无法辩别的收入");
        typeMap.put(TYPE_UNKNOWN, "Unknown transfer/无法辨别的支出");
        typeMap.put(TYPE_DOUBLE_PAYOUT, "Double payout/重复出款");
        typeMap.put(TYPE_SPMC, "SPMC");
        typeMap.put(TYPE_OPENCARD, "Opencard/开卡");
        typeMap.put(TYPE_AJ_FI, "Adjustment/调整");
        typeMap.put(TYPE_AJ_FO, "Adjustment/调整");
        typeMap.put(TYPE_AJ_TOPUP, "Adjustment/调整");
        typeMap.put(TYPE_AJ_BALANCE, "Adjustment/调整");
        typeMap.put(TYPE_TECH_TEST, "Tech Test/技术测试");
        typeMap.put(TYPE_BIMC, "BIMC");
        typeMap.put(TYPE_MA_REBATE, "MA-Rebate");
        typeMap.put(TYPE_SIM_TOPUP, "SIM TOPUP");
        typeMap.put(TYPE_BANK_RENTAL, "Bank Rental");
        typeMap.put(TYPE_OTHERS, "Others/其他");
        typeMap.put(TYPE_REFUND_FRAUD, "Refund - Fraud/退款 - 诈欺");
        typeMap.put(TYPE_REFUND_DEPOSIT, "Refund - Deposit/退款 - 充值");
        typeMap.put(TYPE_BANK_REVERSAL, "Bank Reversal/银行冲账");
        return typeMap.get(type);
    }

    /**
     * 对查询后的一些数据的处理
     *
     * @param respList
     * @return
     */
    private List<NonMerchantStatementResp> afterQueryProcessing(List<NonMerchantStatementResp> respList) {
        return respList.stream().map(resp -> {
            // 处理commandId
            resp.setCommandId(processingCommandId(resp));
            // refVbsId处理
            resp.setRefVbsId(resp.getModelClass().equals("VB") ? resp.getCommandId() : null);
            // 查询history
            resp.setHistory(ObjectUtils.isEmpty(xyExceptionRecordEntityMapper
                    .selectOne(new LambdaQueryWrapper<SysXyExceptionRecordEntity>()
                            .eq(SysXyExceptionRecordEntity::getBankBillId, resp.getVbId()))) ? 0:1);
            // remark获取
            List<SysBankBillRemarkEntity> remarkEntityList = bankBillRemarkEntityMapper.selectList(new LambdaQueryWrapper<SysBankBillRemarkEntity>()
                    .eq(!ObjectUtils.isEmpty(resp.getVbId()), SysBankBillRemarkEntity::getBankBillId, resp.getVbId())
                    .in(SysBankBillRemarkEntity::getRemarkBy, "OTO", "ALL"));
            resp.setRemark(remarkEntityList);
            // TODO note处理
            return resp;
        }).collect(Collectors.toList());
    }

    /**
     * 处理commandId为他添加对应的前缀
     *
     * @return
     */
    private String processingCommandId(NonMerchantStatementResp resp) {
        String altId = null;
        switch (resp.getModelClass()){
            case "TR":
                altId = AltIdUtils.getAltId("I", resp.getCreatedAt(), Long.parseLong(resp.getCommandId()));
                break;
            case "ET":
                altId = AltIdUtils.getAltId("E", resp.getCreatedAt(), Long.parseLong(resp.getCommandId()));
                break;
        }
        return altId;
    }

    /**
     * 查询前进行的处理
     *
     * @param req
     * @return
     */
    private NonMerchantStatementReq preQueryProcessing(NonMerchantStatementReq req) {
        // 通过交易id获取commandId
        String commandId = getCommandIdByAltId(req);
        req.setCommandId(commandId);
        return req;
    }

    /**
     * 通过订单号获取对应订单的commandId
     * @param req
     * @return
     */
    private String getCommandIdByAltId(NonMerchantStatementReq req) {
        String altId = req.getCommandId();
        // 获取前缀
        String prefix = altId.split("-")[0];
        // 获取需要查询的表
        String table = null;
        switch (prefix){
            case "D":
                table = "sys_fi_order";
                break;
            case "W":
                table = "sys_fo_order_main";
                break;
            case "WS":
                table = "sys_fo_order_child";
                break;
            case "S":
                table = "sys_fx_order";
                break;
            case "SS":
                table = "sys_fx_order_child";
                break;
            case "I":
                table = "sys_tr_order";
                break;
            case "E":
                table = "sys_et_order";
                break;
            case "A":
                table = "sys_adjust_order";
                break;
        }
        // 获取commandId
        String commandId = nonMerchantStatementMapper.selectCommandIdById(table, AltIdUtils.restoreId(altId));
        return commandId;
    }
}
